package cn.buk.qms.web;

import cn.buk.common.JsonResult;
import cn.buk.common.dto.CommonDto;
import cn.buk.common.sc.CommonSearchCriteria;
import cn.buk.tms.dto.*;
import cn.buk.tms.sc.SearchCustomerCriteria;
import cn.buk.qms.service.EnterpriseService;
import cn.buk.qms.service.EnterpriseStatService;
import cn.buk.qms.service.UserService;
import cn.buk.tms.common.dto.PaymentMethodDto;
import cn.buk.common.util.DateUtil;

import cn.buk.tms.entity.misc.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import jakarta.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * @author yfdai
 */
@RestController
public class EnterpriseController extends BaseController {

  private static final Logger logger = LogManager.getLogger(EnterpriseController.class);

  @Autowired
  public EnterpriseController(UserService userService,
                              EnterpriseService enterpriseService,
                              EnterpriseStatService enterpriseStatService) {
    this.userService = userService;
    this.enterpriseService = enterpriseService;
    this.enterpriseStatService = enterpriseStatService;
  }

  private final UserService userService;

  private final EnterpriseService enterpriseService;
  private final EnterpriseStatService enterpriseStatService;

  /**
   * 创建修改企业的乘机人信息
   */
  @PostMapping(value = "/passenger", consumes = "application/json")
  public JsonResult createPassenger(HttpServletRequest request,
      @RequestBody PassengerDto dto) {
    final int enterpriseId = getEnterpriseId(request);
    final int userId = getUserId(request);
    final String username = getUsername(request);

    return enterpriseService.savePsgInfo(enterpriseId, userId, username, dto);
  }

  @RequestMapping("/passengers")
  public CommonDto<PassengerDto> searchPassengers(HttpServletRequest request,
      @ModelAttribute("sc") SearchCustomerCriteria sc) {
    final int enterpriseId = getEnterpriseId(request);
    final int userId = getUserId(request);

    List<PassengerDto> passengers = enterpriseService.searchPsgInfo(enterpriseId, userId, sc);

    CommonDto<PassengerDto> commonDto = new CommonDto<>();
    commonDto.setDataList(passengers);
    commonDto.setPage(sc.getPage());

    return commonDto;
  }

  /**
   * 创建乘机人与机票私有政策的关联
   */
  @PostMapping(value = "/passenger-flight-policy")
  public JsonResult savePassengerFlightKeyCustomerPolicy(HttpServletRequest request,
                                    @RequestParam(value = "passengerIds[]") int[] psgIds,
                                    @RequestParam(value = "policyIds[]") int[] policyIds) {
    final int enterpriseId = getEnterpriseId(request);
    final String username = getUsername(request);

    return enterpriseService.savePassengerFlightKeyCustomerPolicy(enterpriseId, username, psgIds, policyIds);
  }

  /**
   * 移除乘机人与机票私有政策的关联
   */
  @DeleteMapping(value = "/passenger/{psgId}/flight-policy/{policyId}")
  public JsonResult removePassengerFlightPolicy(HttpServletRequest request,
                                                         @PathVariable("psgId") int psgId,
                                                         @PathVariable("policyId") int policyId) {
    final int enterpriseId = getEnterpriseId(request);
    final String username = getUsername(request);

    return enterpriseService.removePassengerFlightPolicy(enterpriseId, username, psgId, policyId);
  }

  /**
   * 上传企业乘机人信息
   * @param request
   * @param upfile
   * @return
   */
  @PostMapping(value = "/passengers/upload")
  public JsonResult uploadPassengers(HttpServletRequest request,
                                      MultipartFile upfile,
                                      @RequestParam(value = "customerId", defaultValue = "0") int customerId
  ) {
    final int enterpriseId = getEnterpriseId(request);
    final String username = getUsername(request);

    if (customerId < 1) {
      return JsonResult.createJsonResult(-2, "请选择客户");
    }


    String fileName = getUserId(request) + "0" +  DateUtil.getCurDateTimeString("yyyyMMddHHmmss");

    String filePath = System.getProperty("java.io.tmpdir") +  File.separator + fileName;
    logger.info(filePath);
    File outputFile = new File(filePath);
    try {
      FileCopyUtils.copy(upfile.getBytes(), outputFile);
    } catch (IOException e) {
      e.printStackTrace();
      return JsonResult.createJsonResult(-1, "文件处理失败");
    }

    return enterpriseService.importPassengersByExcel(enterpriseId, username, filePath, customerId);
  }


  /**
   * 乘机人信息
   */
  @GetMapping(value = "/passenger/{id}")
  public PassengerDto getPassenger(HttpServletRequest request,
      @PathVariable("id") int id) {
    final int enterpriseId = getEnterpriseId(request);

    return enterpriseService.getPassengerInfo(enterpriseId, id);
  }

  @DeleteMapping(value = "/passenger/{id}")
  public JsonResult deletePassenger(HttpServletRequest request,
      @PathVariable("id") int id) {
    final int userId = getUserId(request);

    return enterpriseService.deletePassengerInfo(userId, id);
  }

  /**
   * 根据企业客户的员工ID生产对应的登录信息，便于其使用自助服务
   * @param request
   * @param id
   * @return
   */
  @PostMapping(value = "/passenger/{id}/loginInfo")
  public JsonResult generatePassengerLoginInfo(HttpServletRequest request,
                                    @PathVariable("id") int id) {
    final int userId = getUserId(request);

    return enterpriseService.generatePassengerLoginInfo(userId, id);
  }


  /**
   * 导出乘机人信息
   */
  @RequestMapping("/import/passengers")
  public JsonResult importPassengers(HttpServletRequest request) {
    try {
      return enterpriseService.importPassengers(getEnterpriseId(request));
    } catch (Exception ex) {
      ex.printStackTrace();
      return JsonResult.createJsonResult(-1, "exception");
    }
  }



  @RequestMapping("/saveEntCreditLimit.do")
  public JsonResult saveEntCreditLimit(HttpServletRequest request,
      @RequestParam("authorizee") int authorizee,
      @RequestParam("creditLimit") int creditLimit
  ) {
    final int enterpriseId = getEnterpriseId(request);

    return enterpriseService.createEntCreditLimit(enterpriseId, authorizee, creditLimit * 100);
  }

  @RequestMapping("/updateEntCashBalance.do")
  public JsonResult updateEntCashBalance(HttpServletRequest request,
      @RequestParam("id") int id,
      @RequestParam("opMode") int opMode,
      @RequestParam("modifyAmount") int modifyAmount,
      @RequestParam("remark") String remark) {
    final int enterpriseId = getEnterpriseId(request);

    return enterpriseService.updateEntCashBalance(enterpriseId, id, opMode, modifyAmount, remark);
  }

  @RequestMapping("/searchTransactionHistory.do")
  public CommonDto<AmountHistory> searchTransactionHistory(HttpServletRequest request,
                                                           @ModelAttribute("sc") CommonSearchCriteria sc) {
    final int enterpriseId = getEnterpriseId(request);

    CommonDto<AmountHistory> commonDto = new CommonDto<>();

    List<AmountHistory> histories = userService.searchTransactionHistory(enterpriseId, sc);

    commonDto.setDataList(histories);
    commonDto.setPage(sc.getPage());

    return commonDto;
  }


  @RequestMapping("/searchOpHistory.do")
  public CommonDto<LoginHistory> searchOpHistory(HttpServletRequest request,
      @ModelAttribute("sc") CommonSearchCriteria sc) {
    final int enterpriseId = getEnterpriseId(request);
    final String username = getUsername(request);

    CommonDto<LoginHistory> commonDto = new CommonDto<>();

    List<LoginHistory> histories = userService.searchHistory(enterpriseId, username, sc);

    commonDto.setDataList(histories);
    commonDto.setPage(sc.getPage());

    return commonDto;
  }

  /**
   * 查找供应商
   */
  @RequestMapping("/suppliers")
  public CommonDto<SupplierDto> searchSuppliers(HttpServletRequest request,
      @ModelAttribute("sc") CommonSearchCriteria sc) {
    List<SupplierDto> dtos = enterpriseService.searchSuppliers(getEnterpriseId(request), sc);

    CommonDto<SupplierDto> commonDto = new CommonDto<>();
    commonDto.setDataList(dtos);
    commonDto.setPage(sc.getPage());

    return commonDto;
  }

  /**
   * 查找接口API供应商
   */
  @RequestMapping("/tmsSuppliers")
  public List<TmsSupplierDto> searchTmsSuppliers(HttpServletRequest request,
                                                 @ModelAttribute("sc") CommonSearchCriteria sc) {
    return enterpriseService.searchTmsSuppliers(getEnterpriseId(request));
  }

  /**
   * 查找供应商
   */
  @GetMapping("/supplier/{id}")
  public SupplierDto searchSupplier(HttpServletRequest request,
                                                @PathVariable("id") int id) {
    return enterpriseService.searchSupplier(getEnterpriseId(request), id);
  }

  /**
   * 新建/修改供应商
   */
  @PostMapping(value = "/supplier/create")
  public JsonResult createSupplier(HttpServletRequest request,
      @RequestParam("id") int id,
      @RequestParam("name") String name,
      @RequestParam(value = "supplierType", defaultValue = "0") int supplierType,
      @RequestParam("remark") String remark,
      @RequestParam(value = "pinyin", required = false) String pinyin,
      @RequestParam(value = "status", defaultValue = "1") int status,
      @RequestParam(value = "paymentMethodId", defaultValue = "0") int paymentMethodId
  ) {
    final int enterpriseId = getEnterpriseId(request);
    final String username = getUsername(request);

    Supplier supplier = new Supplier();
    supplier.setId(id);
    supplier.setName(name);
    supplier.setSupplierType(supplierType);
    supplier.setRemark(remark);
    supplier.setPinyin(pinyin);
    supplier.setStatus(status);
    supplier.setPaymentMethodId(paymentMethodId);

    return enterpriseService.createSupplier(enterpriseId, username, supplier);
  }

  /**
   * 设置默认供应商
   */
  @PostMapping(value = "/supplier/{id}/default")
  public JsonResult setDefaultSupplier(HttpServletRequest request,
      @PathVariable("id") int supplierId) {
    return enterpriseService.setDefaultSupplier(getEnterpriseId(request), supplierId);
  }

  /**
   * 设置供应商的自动出票属性
   * @param request
   * @param supplierId
   * @param bspType 0-非自动出票，1-BSP自动出票, 2-GP自动出票
   * @return
   */
  @PostMapping(value = "/supplier/{id}/bsp")
  public JsonResult setBspSupplier(HttpServletRequest request,
      @PathVariable("id") int supplierId,
      @RequestParam(value = "status", defaultValue = "1", required = false) final int bspType) {
    return enterpriseService.setBspSupplier(getEnterpriseId(request), supplierId, bspType);
  }

  /**
   * 查找支付方式
   */
  @RequestMapping("/payment/methods")
  public CommonDto<PaymentMethodDto> searchPaymentMethods(HttpServletRequest request,
                                                          @ModelAttribute("sc") CommonSearchCriteria sc) {
    var datas = enterpriseService.searchPaymentMethods(getEnterpriseId(request), sc);

    CommonDto<PaymentMethodDto> commonDto = new CommonDto<>();
    commonDto.setDataList(datas);
    commonDto.setPage(sc.getPage());

    return commonDto;
  }

  /**
   * 新建支付方式
   */
  @PostMapping(value = "/payment/method/create")
  public JsonResult createPaymentMethod(HttpServletRequest request,
      @RequestParam("id") int id,
      @RequestParam("name") String name,
      @RequestParam("pinyin") String pinyin,
      @RequestParam("bankName") String bankName,
      @RequestParam("accountName") String accountName,
      @RequestParam("accountNo") String accountNo,
      @RequestParam("remark") String remark,
      @RequestParam(value = "status", defaultValue = "1") int status
  ) {
    final int enterpriseId = getEnterpriseId(request);

    PaymentMethod pm = new PaymentMethod();
    pm.setId(id);
    pm.setName(name);
    pm.setPinyin(pinyin);
    pm.setBankName(bankName);
    pm.setAccountName(accountName);
    pm.setAccountNo(accountNo);
    pm.setRemark(remark);
    pm.setStatus(status);

    return enterpriseService.createPaymentMethod(enterpriseId, pm);
  }

  /**
   * 查找收款方式备注
   */
  @RequestMapping("/income/methods")
  public CommonDto<IncomeMethodDto> searchIncomeMethods(HttpServletRequest request,
      @ModelAttribute("sc") CommonSearchCriteria sc) {
    final int enterpriseId = getEnterpriseId(request);

    List<IncomeMethodDto> datas = enterpriseService.searchIncomeMethods(enterpriseId, sc);

    CommonDto<IncomeMethodDto> commonDto = new CommonDto<>();
    commonDto.setDataList(datas);
    commonDto.setPage(sc.getPage());

    return commonDto;
  }

  /**
   * 新建收款方式备注
   */
  @PostMapping(value = "/income/method/create")
  public JsonResult createIncomeMethod(HttpServletRequest request,
      @RequestParam("id") int id,
      @RequestParam("name") String name,
      @RequestParam("pinyin") String pinyin,
      @RequestParam("bankName") String bankName,
      @RequestParam("accountName") String accountName,
      @RequestParam("accountNo") String accountNo,
      @RequestParam("remark") String remark) {
    final int enterpriseId = getEnterpriseId(request);

    IncomeMethod o = new IncomeMethod();
    o.setId(id);
    o.setName(name);
    o.setPinyin(pinyin);
    o.setBankName(bankName);
    o.setAccountName(accountName);
    o.setAccountNo(accountNo);
    o.setRemark(remark);

    return enterpriseService.createIncomeMethod(enterpriseId, o);
  }


  /**
   * 查找数据模板
   */
  @RequestMapping("/dataTemplates")
  public CommonDto<DataFieldExportTemplate> searchDataTemplates(HttpServletRequest request,
      @ModelAttribute("sc") CommonSearchCriteria sc) {
    final int enterpriseId = getEnterpriseId(request);
    List<DataFieldExportTemplate> list = enterpriseService.searchDataTemplates(enterpriseId, sc);

    for(DataFieldExportTemplate t: list) {
      for(DataFieldExportInfo fieldInfo: t.getExportFields()) {
        fieldInfo.setTemplate(null);
      }
    }

    CommonDto<DataFieldExportTemplate> commonDto = new CommonDto<>();
    commonDto.setDataList(list);

    return commonDto;
  }

  /**
   * 新建车型组信息
   */
  @PostMapping(value = "/vehicleGroup")
  public JsonResult createVehicleGroup(HttpServletRequest request,
                                       @RequestParam(value = "id", defaultValue = "0") final int id,
                                       @RequestParam("name") String name,
                                       @RequestParam("level") int level,
                                       @RequestParam(value = "remark", required = false) String remark
  ) {
    final int enterpriseId = getEnterpriseId(request);
    final String username = getUsername(request);

    VehicleGroupInfoDto dto = new VehicleGroupInfoDto();
    dto.setId(id);
    dto.setName(name);
    dto.setLevel(level);
    dto.setRemark(remark);

    return enterpriseService.createVehicleGroupInfo(enterpriseId, username, dto);
  }

  /**
   * 查找车型组信息
   */
  @RequestMapping("/vehicleGroups")
  public CommonDto<VehicleGroupInfoDto> searchVehicleGroupInfos(HttpServletRequest request,
                                                                @ModelAttribute("sc") CommonSearchCriteria sc,
                                                                @RequestParam(value = "mapping", defaultValue = "0") int mapping
  ) {
    List<VehicleGroupInfoDto> dtos = enterpriseService
            .searchVehicleGroups(getEnterpriseId(request), sc, mapping);

    CommonDto<VehicleGroupInfoDto> commonDto = new CommonDto<>();
    commonDto.setDataList(dtos);
    commonDto.setPage(sc.getPage());

    return commonDto;
  }

  /**
   * 新建车型组映射
   */
  @PostMapping(value = "/vehicleGroupMapping")
  public JsonResult createVehicleGroupMapping(HttpServletRequest request,
                                              @RequestParam("vehicleId") int vehicleId,
                                              @RequestParam("supplierId") int supplierId,
                                              @RequestParam("supplierVehicleId") int supplierVehicleId
  ) {
    final int enterpriseId = getEnterpriseId(request);
    final String username = getUsername(request);

    return enterpriseService.createVehicleGroupMapping(enterpriseId, username, vehicleId, supplierId, supplierVehicleId);
  }

  /**
   *
   */
  @GetMapping(value = "/passenger_recency")
  public void refreshPassengerRecency(HttpServletRequest request) {

     enterpriseStatService.refreshPassengerRecency();
  }


}
